﻿using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;

#if !PocketPC
using System.Net.Cache;
using System.Net.Security;
using System.Security.Principal;
#endif

namespace SocialKit.LightRest
{
    /// <summary>
    /// Represents the settings used for an HttpWebRequest.
    /// 
    /// </summary>
    public class HttpWebRequestTransportSettings
    {
        X509CertificateCollection certificates;
        IWebProxy proxy;

#if !PocketPC
        HttpRequestCachePolicy cache;

        /// <summary>
        /// Gets or sets the cache policy for an HttpWebRequest.
        /// </summary>
        public HttpRequestCachePolicy CachePolicy
        {
            get
            {
                return cache;
            }
            set
            {
                HasCachePolicy = true;
                cache = value;
            }
        }

        /// <summary>
        /// Gets a boolean value that indicates the CachePolicy whether has a value.
        /// </summary>
        internal bool HasCachePolicy
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets or sets values indicating the level of authentication and impersonation used for an HttpWebRequest.
        /// </summary>
        public AuthenticationLevel? AuthenticationLevel
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the cookies associated with an HttpWebRequest.
        /// </summary>
        public CookieContainer Cookies
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the impersonation level for the an HttpWebRequest.
        /// </summary>
        public TokenImpersonationLevel? ImpersonationLevel
        {
            get;
            set;
        }

        /// <summary>
        /// Sets the cache policy property of current settings with specified cache level.
        /// </summary>
        /// <param name="level"></param>
        public void SetCacheLevel(System.Net.Cache.HttpRequestCacheLevel level)
        {
            this.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(level);
        }

        /// <summary>
        /// Gets or sets a System.Boolean value that controls whether System.Net.CredentialCache.DefaultCredentials are sent with requests.
        /// </summary>
        public bool? UseDefaultCredentials
        {
            get;
            set;
        }

#endif
        /// <summary>
        /// Gets or sets a value that indicates whether to buffer the data sent to the server.
        /// </summary>
        public bool? AllowWriteStreamBuffering
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the type of decompression that is used.
        /// </summary>
        public DecompressionMethods? AutomaticDecompression
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the collection of security certificates that are associated with this request.
        /// </summary>
        public X509CertificateCollection ClientCertificates
        {
            get
            {
                if (certificates == null)
                {
                    certificates = new X509CertificateCollection();
                }
                return certificates;
            }
        }

        /// <summary>
        /// Gets or sets authentication information for the request.
        /// </summary>
        public ICredentials Credentials
        {
            get;
            set;
        }


        int redirects = 50;

        /// <summary>
        /// Gets or sets the maximum number of redirects that the request follows.
        /// </summary>
        public int MaximumAutomaticRedirections
        {
            get
            {
                return this.redirects;
            }
            set
            {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("value", "MaximumAutomaticRedirections must be greater than or equal to zero");
                }
                this.redirects = value;
            }
        }

        /// <summary>
        /// Gets or sets the maximum allowed length of the response headers.
        /// </summary>
        public int? MaximumResponseHeaderKB
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets a value that indicates whether to send an authenticate header
        /// with the request.
        /// </summary>
        public bool? PreAuthenticate
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets proxy information for the request.
        /// </summary>
        public IWebProxy Proxy
        {
            get
            {
                return proxy;
            }
            set
            {
                HasProxy = true;
                proxy = value;
            }
        }

        /// <summary>
        /// Gets or sets a time-out in milliseconds when writing to or reading from a stream.
        /// </summary>
        public TimeSpan? ReadWriteTimeout
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets a value that indicates whether to send data in segments to the server.
        /// </summary>
        public bool? SendChunked
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the time-out value in milliseconds for the System.Net.HttpWebRequest.GetResponse()
        /// and System.Net.HttpWebRequest.GetRequestStream() methods.
        /// </summary>
        public TimeSpan? ConnectionTimeout
        {
            get;
            set;
        }

        /// <summary>
        /// Gets a boolean value that indicates the ClientCertificates whether has a value.
        /// </summary>
        internal bool HasClientCertificates
        {
            get
            {
                return certificates != null && certificates.Count != 0;
            }
        }

        /// <summary>
        /// Gets a boolean value that indicates the Proxy property whether has a value.
        /// </summary>
        internal bool HasProxy
        {
            get;
            private set;
        }
    }
}